#define __TITLE     "Hypo-Alg Test"

#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>

bool key[ 321 ];
bool lastkey[ 320 ];
int last;
swarmBin * sb;
int segLast;


//int window_width  = 1024;
//int window_height = 768;

int window_width  = 1440;
int window_height = 900;



void GL_Setup( int width, int height ) {
	SDL_WM_SetCaption( __TITLE, "" );
	glViewport(   0, 0, width, height );
	glMatrixMode( GL_PROJECTION );
	glDisable(    GL_DEPTH_TEST );
	glLoadIdentity();
	glOrtho (0, width, height, 0, 0, 1);
	glMatrixMode( GL_MODELVIEW );
}

SDL_Surface * GL_Init( int width, int height ) {
	SDL_Init(SDL_INIT_VIDEO);
	const SDL_VideoInfo* info = SDL_GetVideoInfo();
	int vidFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_FULLSCREEN;
	if ( info->hw_available ) {
		vidFlags |= SDL_HWSURFACE;
	} else {
		vidFlags |= SDL_SWSURFACE;
	}
	int bpp = info->vfmt->BitsPerPixel;
	SDL_Surface * ret = SDL_SetVideoMode(width, height, bpp, vidFlags);
	GL_Setup(width, height);
	return ret;
}

void use_color( int r, int g, int b ) {
	glColor3ub( r, g, b );
}

void clear() {
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
}

void render() {
	glEnd();
	SDL_GL_SwapBuffers();
}

int getNode( int x, int nx, int ny ) {
	return (x * nx) + ny;
}
float get_start_x( float x, float boxx ) {
	return x * boxx;
}
float get_start_y( float y, float boxy ) {
	return y * boxy;
}
float get_end_x(   float x, float boxx ) {
	return x * boxx + boxx;
}
float get_end_y(   float y, float boxy ) {
	return y * boxy + boxy;
}

void draw_square( int x1, int y1, int x2, int y2 ) {
	glBegin(GL_QUADS);
	glVertex2f(x1, y1);
	glVertex2f(x2, y1);
	glVertex2f(x2, y2);
	glVertex2f(x1, y2);
}

bool shouldContine( SDL_Event * e ) {
	bool ret = true;

	if ( SDL_PollEvent( e ) ) {
		switch( e->type ) {
			case SDL_KEYDOWN:
				key[ e->key.keysym.sym ] = true ;
				break;
			case SDL_QUIT:
				ret = false;
				break;
		}
	}

	if ( key[SDLK_q] && ! lastkey[SDLK_q] ) {
		ret = false;
	}

	return ret;
}

void drawWiimote( wiiIface * wi ) {

	if ( wi->shouldReset() ) {
		for ( int ix = 0; ix < sb->getX(); ++ix ) {
			for ( int iy = 0; iy < sb->getY(); ++iy ) {
				sb->getNode(ix, iy)->unfreezeNode();
			}
		}
	}

	int x = wi->getWiiX();
	int y = wi->getWiiY();

	float box_x = window_width  / (float)sb->getX();
	float box_y = window_height / (float)sb->getY();

	int boxx = x / box_x;
	int boxy = y / box_y;

	if ( wi->shouldDraw() ) {
		sb->getNode( boxx, boxy )->freezeNode();
	}

	// sb->getNode( boxx, boxy )->setStatus(wi->getColor());
	// sb->getNode( boxx, boxy )->rateHypoExcept(wi->getColor(), -5 );

}

void * thread_gfx( void * ptr ) {

	wiiIface * wi = new wiiIface();


	pthread_t wIF;
	pthread_create( &wIF, NULL, thread_wiiIface, wi  );

	sb = static_cast <swarmBin *> (ptr);

	int status;

	int x;
	int y;

	float box_x;
	float box_y;

	float start_x;
	float start_y;

	float end_x;
	float end_y;

	bool render = true;

	x = sb->getX();
	y = sb->getY();

	box_x = window_width  / (float)x;
	box_y = window_height / (float)y;

	box_x = (int)(box_x + 0.99f);
	box_y = (int)(box_y + 0.99f);

	SDL_Event e;
	SDL_Event * event = &e;

	bool key[ 321 ];
	bool lastkey[ 320 ];

	GL_Init( window_width, window_height );

	while ( ! sb->binIsComplete() ) {
		usleep( 200 );

		for ( int ix = 0; ix < x; ++ix ) 	{
			for ( int iy = 0; iy < y; ++iy ) {
				if ( shouldContine( event ) ) {
					status = sb->getNode( ix, iy)->getStatus();

					start_x = get_start_x( ix, box_x );
					start_y = get_start_y( iy, box_y );
					end_x   = get_end_x  ( ix, box_x );
					end_y   = get_end_y  ( iy, box_y );	

//					if ((( iy % 2 == 0 ) && ( ix % 2 == 0 )) && ( status == 0 ) && last != 0 ) { use_color( 41, 26, 6   ); last = 0; }
//					if ((( iy % 2 == 1 ) && ( ix % 2 == 1 )) && ( status == 0 ) && last != 0 ) { use_color( 41, 26, 6   ); last = 0; }
//					if ((( iy % 2 == 0 ) && ( ix % 2 == 0 )) && ( status == 1 ) && last != 1 ) { use_color( 125, 79, 19 ); last = 1; }
//					if ((( iy % 2 == 1 ) && ( ix % 2 == 1 )) && ( status == 1 ) && last != 1 ) { use_color( 125, 79, 19 ); last = 1; }

					if ((( iy % 2 == 0 ) && ( ix % 2 == 0 )) && ( status == 0 ) && last != 0 ) { use_color( 1, 4, 5   ); last = 0; }
					if ((( iy % 2 == 1 ) && ( ix % 2 == 1 )) && ( status == 0 ) && last != 0 ) { use_color( 1, 4, 5   ); last = 0; }
					if ((( iy % 2 == 0 ) && ( ix % 2 == 0 )) && ( status == 1 ) && last != 1 ) { use_color( 17, 70, 91 ); last = 1; }
					if ((( iy % 2 == 1 ) && ( ix % 2 == 1 )) && ( status == 1 ) && last != 1 ) { use_color( 17, 70, 91 ); last = 1; }


					if ( sb->getNode(ix, iy)->isLocked() ) {
						use_color( 67, 117, 56 );
						last = -1;
					}
					if ( sb->getNode(ix, iy)->isFrozen() && last == 0 ) {
						use_color( 9, 174, 215 );
						last = -1;
					}
					if ( sb->getNode(ix, iy)->isFrozen() && last == 1 ) {
						use_color( 55, 103, 127 );
						last = -1;
					}

					draw_square( start_x, start_y, end_x, end_y );
					drawWiimote( wi );

				} else {
					std::cout << "Killing Exec Violently from GFX, Rcvd Kill Sig\n";
					exit(0);
				}
			}
		}
		glEnd();
		SDL_GL_SwapBuffers();
	}
	void * ret = NULL;
	return ret;
}

